package com.ifinc.common.web.frame;

import com.ifinc.common.exception.ConfigException;
import com.ifinc.common.web.frame.define.Param;
import com.ifinc.common.web.frame.define.Persistence;
import org.apache.log4j.Logger;

import java.lang.reflect.Method;
import java.util.Map;

/**
 * User: luotao
 * Date: 13-11-28
 * Time: 13:37
 */
public class Executor {

    private static Logger logger = Logger.getLogger(Executor.class);

    protected ClassInfo classInfo;

    protected Object invokeObject;

    protected ConfigContext configContext;

    protected Method invokeMethod;

    public Executor(ClassInfo classInfo, ConfigContext configContext) {
        this.classInfo = classInfo;
        invokeObject = classInfo.newInstance();
        if (!(invokeObject instanceof Persistence)) {
            throw new ConfigException("class:%s must implements " + Persistence.class.getName(), classInfo.getFullClassName());
        }
        if (!(invokeObject instanceof Param)) {
            throw new ConfigException("class:%s must implements " + Param.class.getName(), classInfo.getFullClassName());
        }
        this.configContext = configContext;
        setDao();
    }

    public void setDao() {
        Persistence param = (Persistence) invokeObject;
        param.setDao(configContext.getDao());
    }

    public void setConfigContext() {
        Param param = (Param) invokeObject;
        param.setConfigContext(configContext);
    }

    public Object execute(String methodName) {
        verifyClassType();

        invokeMethod = classInfo.getMethod(methodName);

        verifyMethod();

        verifyInput();

        return classInfo.invokeMethod(invokeObject, methodName);
    }

    public void verifyInput() {
        Param param = (Param) invokeObject;
        param.verify(invokeMethod.getName());
    }

    public void verifyClassType() {

    }

    public void setParams(Map reqParam, Map sessionMap, Map headerMap, String methodName) {
        logger.info("setup reqParam   for " + classInfo.getFullClassName() + "." + methodName + " : " + reqParam);
        logger.info("setup sessionMap for " + classInfo.getFullClassName() + "." + methodName + " : " + sessionMap);
        logger.info("setup headerMap  for " + classInfo.getFullClassName() + "." + methodName + " : " + headerMap);
        Param param = (Param) invokeObject;
        param.setReqParam(reqParam);
        param.setSessionMap(sessionMap);
        param.setHeaderParam(headerMap);
    }

    public void verifyMethod() {

    }

    public Map<String, Object> getSessionMap() {
        Param param = (Param) invokeObject;
        Map sessionMap = param.getSessionMap();
        logger.info("sessionMap in " + classInfo.getFullClassName() + "." + invokeMethod.getName() + " : " + sessionMap);
        return param.getSessionMap();
    }

    public Map<String, Object> getResultMap() {
        Param param = (Param) invokeObject;
        Map resultMap = param.getResultMap();
        logger.info("resultMap  in " + classInfo.getFullClassName() + "." + invokeMethod.getName() + " : " + resultMap);
        return resultMap;
    }


}
